package com.fgba.express.data.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fgba.express.comm.enums.State;
import com.fgba.express.core.service.impl.CrudServiceImpl;
import com.fgba.express.data.dao.IRoleDao;
import com.fgba.express.data.dao.IRoleMenuMappingDao;
import com.fgba.express.data.dto.RoleDto;
import com.fgba.express.data.entity.Role;
import com.fgba.express.data.entity.RoleMenuMapping;
import com.fgba.express.data.entity.User;
import com.fgba.express.data.entity.UserRoleMapping;
import com.fgba.express.data.mapstruct.RoleStruct;
import com.fgba.express.data.search.RoleSearch;
import com.fgba.express.data.service.IRoleMenuMappingService;
import com.fgba.express.data.service.IRoleService;
import com.fgba.express.data.service.IUserRoleMappingService;
import com.fgba.express.util.BeanContextUtil;
import com.fgba.express.util.NullChecker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.annotation.Transient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author fgba
 * @since 2022-02-24
 */
@Service
public class RoleServiceImpl extends CrudServiceImpl<IRoleDao, Role, RoleDto, RoleSearch,RoleStruct> implements IRoleService {
    @Resource
    private IRoleMenuMappingService roleMenuMappingService;

    @Override
    public boolean removeById(Serializable id) {
        Role role = baseMapper.selectById(id);
        role.setState(State.STATUS_AVAILABLE);
        role.setModifiedTime(LocalDateTime.now());
        baseMapper.updateById(role);
        return true;
    }
    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        List<Role> roles = baseMapper.selectBatchIds(idList);
        boolean flag = true;
        for (Role role : roles) {
            role.setState(State.STATUS_AVAILABLE);
            role.setModifiedTime(LocalDateTime.now());

            if (!(baseMapper.updateById(role) > 0)) {
                flag = false;
            }
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignMenu(Long roleId, List<Long> menuIds) {
        List<RoleMenuMapping> roleMenuMappings = new LinkedList<>();
        for (Long menuId : menuIds) {
            RoleMenuMapping roleMenuMapping = new RoleMenuMapping();
            roleMenuMapping.setMenuId(menuId);
            roleMenuMapping.setRoleId(roleId);
            roleMenuMappings.add(roleMenuMapping);
        }
        roleMenuMappingService.remove(Wrappers.<RoleMenuMapping>lambdaQuery().eq(RoleMenuMapping::getRoleId, roleId));
        return roleMenuMappingService.saveBatch(roleMenuMappings);
    }

    @Override
    public List<Role> getRolesByUserId(Long userId) {
        List<UserRoleMapping> userRoleMappings = BeanContextUtil.getBean(IUserRoleMappingService.class).list(Wrappers.<UserRoleMapping>lambdaQuery().eq(UserRoleMapping::getUserId, userId));
        if (NullChecker.isNull(userRoleMappings)) {
            return new ArrayList<>();
        }
        return listByIds(userRoleMappings.stream().map(UserRoleMapping::getRoleId).collect(Collectors.toList()));
    }
}
